package com.fsoft.core.aop;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang.StringUtils;
import org.apache.logging.log4j.core.config.Order;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.alibaba.fastjson.JSON;
import com.fsoft.core.annotation.SystemLog;
import com.fsoft.core.common.base.entity.UserVo;
import com.fsoft.core.context.FSContext;
import com.fsoft.core.sys.entity.SysLog;
import com.fsoft.core.sys.service.SysLogService;
import com.fsoft.core.utils.DateTimeUtils;
import com.fsoft.core.utils.HttpContextUtils;
import com.fsoft.core.utils.OgnlUtils;
import com.fsoft.core.utils.RetVo;
import com.fsoft.core.utils.WebUtils;

/**
 * F-Soft 系统日志切面
 * @package com.fsoft.core.aop
 * @author Fish
 * @email it.fish2010@foxmail.com
 * @date 2019-11-25
 * @CopyRight © F-Soft
 **/
@Aspect
@Component
@Order(1)
public class SysLogAspect {
	@Autowired
	private SysLogService sysLogService;
	private long startTime = 0;
	private UserVo user;

	/**
	 * F-Soft 在需要记录日志的Controller，使用@SysLog 标签，可实现日志记录
	 * @author Fish(it.fish2010@foxmail.com)
	 * @date 2019-12-11
	 */
	@Pointcut("@annotation(com.fsoft.core.annotation.SystemLog)")
	public void logPointCut() {

	}

	@Around("logPointCut()")
	public Object saveSysLog(ProceedingJoinPoint joinPoint) throws Throwable {
		try {
			this.startTime = System.currentTimeMillis();
			this.user = FSContext.getInstance().getUser();
			Object obj = joinPoint.proceed();
			if (!(obj instanceof RetVo))
				return obj;
			RetVo vo = (RetVo) obj;
			if (!(vo.getCode() == 0))
				return obj;

			MethodSignature signature = (MethodSignature) joinPoint.getSignature();
			// 系统日志的Bean
			SysLog entity = new SysLog();
			SystemLog systemLog = signature.getMethod().getAnnotation(SystemLog.class);
			// 操作
			entity.setOperateName(systemLog.value());
			// 请求的方法名
			String className = joinPoint.getTarget().getClass().getName();
			String methodName = signature.getName();
			entity.setMethod(className + "." + methodName + "()");
			// 请求的参数
			Object[] args = joinPoint.getArgs();
			StringBuffer params = new StringBuffer();
			for (Object arg : args) {
				if (OgnlUtils.isNotEmpty(arg))
					params.append(JSON.toJSONString(arg));
			}
			entity.setParams(params.toString());
			// 获取request
			HttpServletRequest request = HttpContextUtils.getHttpServletRequest();
			// 设置IP地址
			entity.setIp(WebUtils.getIpAddr(request));
			entity.setCreateTime(DateTimeUtils.getNowTime());
			if (user == null)
				user = FSContext.getInstance().getUser(); // 登录操作，执行方法前，uservo为空
			if (user != null) {
				entity.setCreateUserId(user.getId()); // 操作人ID
				StringBuffer operation = new StringBuffer();
				operation.append("用户[" + user.getName() + "(" + user.getLoginAcct() + ")]");
				operation.append("执行操作[" + systemLog.value() + "],");
				operation.append("操作时间:").append(DateTimeUtils.formatDateTime(entity.getCreateTime()));
				if (StringUtils.isNotBlank(entity.getIp()))
					operation.append(",客户端IP：").append(entity.getIp());
				entity.setOperation(operation.toString());
			}
			// 保存系统日志
			long times = System.currentTimeMillis() - startTime;
			if (startTime > 0)
				entity.setRemark("耗时:" + times + "ms");
			sysLogService.save(entity);
			return obj;
		} catch (Exception e) {
			throw e;
		}
	}

}
